﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Project.Core.Config.Common.Lang;
using Project.Core.Config.Common.Utils;
using Project.Core.Config.Config.Jwt;
using Project.Core.Test.Entity;
using Project.Core.Test.Entity.Input;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;

namespace Project.Core.Test.Controllers {
    /// <summary>
    /// 用户接口
    /// </summary>
    public class SysUserController : TestController<SysUserController> {

        /// <summary>
        /// 获取验证码图片
        /// </summary>
        /// <response code="200">返回验证码图片</response>
        /// <returns></returns>
        [HttpGet]
        [Route("/captcha")]
        [AllowAnonymous]
        public Result Captcha() {

            string key = Guid.NewGuid().ToString();
            string code = Producer.CreateText();

            // 为了测试
            //string key = "aaaaa";
            //string code = "11111";

            Bitmap bitmap = Producer.CreateImage(code);
            string base64Img = "data:image/jpeg;base64," + Producer.ToBitmapBase64(bitmap);

            // 存储到redis中
            Cache.Set(key, code, 120);
            Logger.LogInformation("验证码 -- {} - {}", key, code);

            return Result.Succ(new Dictionary<string, string> {
                ["captchaImg"] = base64Img,
                ["token"] = key
            });
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <response code="200">返回用户信息</response>
        /// <returns></returns>
        [HttpGet]
        [Route("/sys/userInfo")]
        [Authorize]
        public Result UserInfo() {
            var user = SysUserService.GetByUsername(HttpContext.User.Identity.Name);

            return Result.Succ(new Dictionary<string, string> {
                ["id"] = user.Id.ToString(),
                ["username"] = user.UserName,
                ["avatar"] = user.Avatar,
                ["created"] = user.Created.ToString("yyyy-MM-dd HH:mm:ss")
            });
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("/register")]
        public Result register(SysUserInput userInput) {
            if (!Regex.IsMatch(userInput.Phone, @"^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$")) {
                return Result.Fail("输入的手机号码有误");
            }
            if (!Regex.IsMatch(userInput.Email, @"[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?")) {
                return Result.Fail("输入的邮箱有误");
            }
            SysUser adminUser = new SysUser() {
                UserName = userInput.Username,
                Password = Producer.Encrypt(userInput.Password),
                Phone = userInput.Phone,
                Email = userInput.Email,
                Avatar = Const.DEFULT_AVATAR,
                Created = DateTime.Now,
            };

            if (SysUserService.Register(adminUser)) {
                return Result.Succ("注册成功");
            } else {
                return Result.Fail("该用户名已经被注册，请修改重新输入用户名");
            }
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="code">验证码</param>
        /// <param name="key">验证码token</param>
        /// <response code="200">验证通过返回用户token</response>
        /// <returns></returns>
        [HttpPost]
        [Route("/login")]
        [AllowAnonymous]
        public Result login(string username, string password, string code, string key) {

            if (code.IsNullOrEmpty() || key.IsNullOrEmpty()) {
                return Result.Fail("请输入验证码");
            } else {
                string cpCode = Cache.Get<string>(key);

                if (code == cpCode) {
                    if (username.IsNullOrEmpty() || password.IsNullOrEmpty()) {
                        return Result.Fail("请输入用户名或者密码");
                    } else {
                        password = Producer.Encrypt(password);
                        var user = SysUserService.Login(username, password);
                        if (user != null) {
                            //string token = getToken(username, user.authorities);
                            var jwtConfig = Configuration.GetSection("JwtConfig").Get<JwtConfigInfo>();
                            string token = JwtToken.GetToken(jwtConfig, username, user.Authorities);
                            //把token存进缓存，过期时间为token的4倍
                            Cache.Set("Bearer " + token, username, jwtConfig.Expires * 4);

                            StringBuilder rolesStr = new StringBuilder();
                            StringBuilder permsStr = new StringBuilder();
                            foreach (var data in user.Authorities) {
                                if (data.Contains(':')) {
                                    if (permsStr.Length==0) {
                                        permsStr.Append(data);
                                    } else {
                                        permsStr.Append("," + data);
                                    }
                                } else {
                                    if (rolesStr.Length == 0) {
                                        rolesStr.Append(data);
                                    } else {
                                        rolesStr.Append("," + data);
                                    }
                                }
                            }

                            return Result.Succ(new Dictionary<string, string> {
                                ["access_token"] = token,
                                ["token_type"] = "Bearer",
                                ["roles"] = rolesStr.ToString(),
                                ["perms"] = permsStr.ToString()
                            });
                        } else {
                            return Result.Fail("用户名或者密码错误");
                        }
                    }
                } else {
                    return Result.Fail("验证码错误");
                }
            }
        }

        /// <summary>
        /// 密码修改
        /// </summary>
        [HttpPost]
        [Route("/repass")]
        public Result repass(SysUserRepassInput repassInput) {
            repassInput.NewPassword = Producer.Encrypt(repassInput.NewPassword);
            repassInput.OldPassword = Producer.Encrypt(repassInput.OldPassword);
            if (SysUserService.Repass(repassInput)) {
                return Result.Succ("修改成功");
            } else {
                return Result.Fail("填写信息有误，重置失败");
            }
        }

        /// <summary>
        /// 用户登出
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("/logout")]
        [Authorize]
        public Result logout() {
            Debug.WriteLine("登出成功");

            var jwtConfig = Configuration.GetSection("JwtConfig").Get<JwtConfigInfo>();

            List<string> authorizations = new List<string>();
            if (!string.IsNullOrEmpty(HttpContext.User.Identity.Name)) {
                if (Cache.IsExist(HttpContext.User.Identity.Name)) {
                    authorizations = Cache.Get<List<string>>(HttpContext.User.Identity.Name);
                }
                if (!string.IsNullOrEmpty(HttpContext.Request.Headers["Authorization"])) {
                    authorizations.Add(HttpContext.Request.Headers["Authorization"]);
                    //把登出的令牌放进缓存（放进缓存的令牌不能再次登录）
                    Cache.Set(HttpContext.User.Identity.Name, authorizations, jwtConfig.Expires);
                }
            }
            if (Cache.IsExist(HttpContext.Request.Headers["Authorization"])) {
                Cache.Remove(HttpContext.Request.Headers["Authorization"]);
            }
            return Result.Succ("登出成功");
        }
    }
}
